﻿#include "study07.h"
// C/C++ 学习网站：https://legacy.cplusplus.com 注意旧版本（搜索）和新版本

// 宏定义的名可以是常量，可以赋值，便于阅读
/*
#ifndef _Debug
	#define _Debug 0
	#if _Debug != 0
		#define my_log(format,...) printf(format, ##__VA_ARGS__)      // 不被预处理加载
	#else
		#define my_log() printf("This is a release version.\n")    // 被预处理加载
	#endif
#endif
*/

/*
// 这里需要在 右键当前项目 -> 属性 -> C/C++ -> 预处理器 -> 预处理定义 中添加 MyDebug 和 MyRelease 两个宏定义
	进入窗口后找到左上角 配置(C)选择 Debug，右侧平台(P)选择所有平台，在预处理器定义中输入 MyDebug[=1]。  [] 表示可选
	选择 配置(C)选择 Release，右侧平台(P)选择所有平台，在预处理器定义中输入 MyRelease[=1]，然后保存即可测试以下的预处理代码。
*/

// 这里的 not defined(MyDebug) 用于判断是否手动定义了 MyDebug 宏
#if defined(_DEBUG) && not defined(MyDebug)
	#define MyDebug 1
#elif defined(NDEBUG) && not defined(MyRelease)
	#define MyRelease 1
#endif

#ifdef MyDebug
	#define my_log(format,...) printf(format, __VA_ARGS__)
#elif defined(MyRelease)     // 同下面的 #else 部分代码
	#define my_log() printf("This is a release version.\n")
/*#else
	#ifdef MyRelease
		#define my_log() printf("This is a release version.\n")
	#else
		#define my_log() printf("unknow version\n")
	#endif */
	/*#else
		#define my_log() printf("unknow version\n") */
#endif

static char* my_strcat(char* dest, const char* src) {
	char* ret = dest;
	while (*dest++);
	/*while (*src)
		*dest++ = *src++;
	*dest = '\0'; // 追加结束符 */
	while (*dest++ = *src++);
	return ret;
}

static auto hello_name(const char* name) -> string // C++11 新特性 -> 定义返回值类型
{ // 这里 char 不能使用 auto 关键字
	string str = "hello ";
	str += name;
	return str;
}

void test_macro_auto()
{
	print_start("宏与 auto 关键字测试");
	my_log("测试 Debug 版本的宏 my_log() 输出:\n%s", "hello world!\n");

	// auto 自动类型推导
	int a = 10;
	auto b = a;
	auto c = 10.5l; // long double 类型
	cout << "a = " << a << "    "
		<< "b = " << b << "    "
		<< "c = " << c << '\n';
	char str[30] = "my string is ";
	string str_cat = my_strcat(str, "Tom"); // ok 会有类型转化
	cout << str_cat << endl;
	auto str_cat2 = hello_name("Tom");
	cout << str_cat2 << endl;

	// 测试迭代器的使用
	std::vector<string> str_vec;
	str_vec.resize(5);
	str_vec.emplace_back("first");
	str_vec.emplace_back("second");
	str_vec.emplace_back("third");
	str_vec.emplace_back("fourth");
	str_vec.emplace_back("fifth");
	//std::vector<string>::iterator it;
	 // 迭代器类型自动推导
	for (auto it = str_vec.begin(); it != str_vec.end(); ++it) // 迭代器类型自动推导
		cout << *it << "    ";
	cout << endl;

	// unorder_map 容器的使用
	std::unordered_map<string, int> str_map;
	str_map["apple"] = 10;

	DeviceManager dm1;
	string name1 = "dm1";
	Device* d1 = new Device();
	d1->set_name("device1");
	Device* d2 = new Device();
	d2->set_name("device2");
	Device* d3 = new Device();
	d3->set_name("device3");
	dm1.add_device(name1, d1);
	dm1.add_device(name1, d2);
	dm1.add_device(name1, d3);
	auto& ret1 = dm1.get_device(name1); // ret1 是一个 vector<Device*> 即指针数组类型的引用
	cout << (*ret1.begin())->get_name() << endl;
	for (auto it = ret1.begin(); it != ret1.end(); ++it)
		cout << (*it)->get_name() << "    ";
	cout << endl;
	dm1.remove_device(name1, d2);
	for (auto it = ret1.begin(); it != ret1.end(); ++it)
		cout << (*it)->get_name() << "    ";
	cout << endl;
	delete d1; // 释放内存
	delete d2;
	delete d3;
	print_end("宏与 auto 关键字测试");
}